package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"strings"
	"test/dnsTest/dns"
	"github.com/remeh/sizedwaitgroup"
	//"test/dnsTest/dns"
	"time"
)

var (
	dnsUrl           = flag.String("dns", "114.114.114.114:53", "dns url")
	in   = flag.String("in", "./domain.txt", "in file path")
	out  = flag.String("out","./result.txt","out file path")
	num  = flag.Int("g",1,"limit groutine num")
)


func main(){
	flag.Parse()
	inFilePath := *in
	outFilePath := *out
	dnsUrl := *dnsUrl
	//outFilePath := *out
	if dnsUrl == "" {
		fmt.Println("dns 请求地址不为空")
		return
	}
	if !Exists(inFilePath) {
		fmt.Println("请检查输入文件是否存在")
		return
	}

	start1 := time.Now()
	FileHandle, err := os.Open(inFilePath)
	if err != nil {
		log.Println("打开输入文件错误:",err)
		return
	}
	defer FileHandle.Close()
	lineReader := bufio.NewReader(FileHandle)

	writeFileHandle,err := os.OpenFile(outFilePath,os.O_CREATE|os.O_TRUNC|os.O_WRONLY,0666)
	if err != nil {
		fmt.Println("open file failed,err:",err)
		return
	}

	//5、关闭文件流
	defer writeFileHandle.Close()
	//2、创建writer对象
	writer := bufio.NewWriter(writeFileHandle)
	group := sizedwaitgroup.New(*num)
	for {
		// 相同使用场景下可以采用的方法
		// func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
		// func (b *Reader) ReadBytes(delim byte) (line []byte, err error)
		// func (b *Reader) ReadString(delim byte) (line string, err error)
		line, _, err := lineReader.ReadLine()
		//fmt.Println("line",string(line))
		if err == io.EOF {
			break
		}
		newLine := make([]byte,len(line))
		copy(newLine,line)
		group.Add()
		go func(writer *bufio.Writer,newLine []byte) {
			if string(newLine) == "" {
				return
			}

			// 如下是某些业务逻辑操作
			// 如下代码打印每次读取的文件行内容
			url := string(newLine)
			oldUrl := url
			if !strings.HasSuffix(url, ".") {
				url = url + "."
			}
			if !strings.HasPrefix(url, "www.") {
				url = "www."+url
			}
			res := dns.DnsRequest(dnsUrl, url)
			fmt.Println(res)
			writer.WriteString(oldUrl +","+ res+"\r\n")
			defer group.Done()
		}(writer,newLine)

	}
	group.Wait()
	writer.Flush()
	fmt.Println("readEachLineReader spend : ", time.Now().Sub(start1))
}


// 判断所给路径文件/文件夹是否存在

func Exists(path string) bool {
	_, err := os.Stat(path)    //os.Stat获取文件信息

	if err != nil {

		if os.IsExist(err) {

			return true

		}

		return false

	}

	return true

}
